package cc.shacocloud.mirage.utils;

import cc.shacocloud.mirage.utils.annotation.AnnotatedElementUtils;
import cc.shacocloud.mirage.utils.reflection.ParameterNameDiscoverer;
import kotlin.Unit;
import kotlin.reflect.KFunction;
import kotlin.reflect.KParameter;
import kotlin.reflect.jvm.ReflectJvmMapping;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;

/**
 * 封装方法参数规范的帮助程序类
 * <p>
 * 参考 spring 实现
 */
public class MethodParameter {
    
    private final Executable executable;
    
    private final int parameterIndex;
    
    /**
     * 从整数级别映射到整数类型索引
     */
    @Nullable
    Map<Integer, Integer> typeIndexesPerLevel;
    
    @Nullable
    private volatile Parameter parameter;
    
    private int nestingLevel;
    
    /**
     * 包含类。也可以通过覆盖 {@link #getContainingClass} 来提供
     */
    @Nullable
    private volatile Class<?> containingClass;
    
    @Nullable
    private volatile Class<?> parameterType;
    
    @Nullable
    private volatile Type genericParameterType;
    
    @Nullable
    private volatile Annotation[] parameterAnnotations;
    
    @Nullable
    private volatile ParameterNameDiscoverer parameterNameDiscoverer;
    
    @Nullable
    private volatile String parameterName;
    
    @Nullable
    private volatile MethodParameter nestedMethodParameter;
    
    
    /**
     * 为给定方法创建一个新的 {@code 方法参数}，嵌套级别为 1
     *
     * @param method         方法对象
     * @param parameterIndex 参数的索引：-1 表示方法返回类型;0 表示第一个方法参数;1 表示第二个方法参数，依此类推。
     */
    public MethodParameter(@NotNull Method method, int parameterIndex) {
        this(method, parameterIndex, 1);
    }
    
    /**
     * 为给定方法创建一个新的 {@code 方法参数}，嵌套级别为 1
     *
     * @param method         方法对象
     * @param parameterIndex 参数的索引：-1 表示方法返回类型;0 表示第一个方法参数;1 表示第二个方法参数，依此类推。
     * @param nestingLevel   目标类型的嵌套级别（通常为 1;例如，在列表列表的情况下，1 表示嵌套列表，而 2 表示嵌套列表的元素）
     */
    public MethodParameter(@NotNull Method method, int parameterIndex, int nestingLevel) {
        this.executable = method;
        this.parameterIndex = validateIndex(method, parameterIndex);
        this.nestingLevel = nestingLevel;
    }
    
    /**
     * 为给定构造函数创建一个嵌套级别为 1 的新方法参数。
     *
     * @param constructor    构造函数对象
     * @param parameterIndex 参数的索引：-1 表示方法返回类型;0 表示第一个方法参数;1 表示第二个方法参数，依此类推。
     */
    public MethodParameter(Constructor<?> constructor, int parameterIndex) {
        this(constructor, parameterIndex, 1);
    }
    
    /**
     * Create a new MethodParameter for the given constructor.
     *
     * @param constructor    构造函数对象
     * @param parameterIndex 参数的索引：-1 表示方法返回类型;0 表示第一个方法参数;1 表示第二个方法参数，依此类推。
     * @param nestingLevel   目标类型的嵌套级别（通常为 1;例如，在列表列表的情况下，1 表示嵌套列表，而 2 表示嵌套列表的元素）
     */
    public MethodParameter(@NotNull Constructor<?> constructor, int parameterIndex, int nestingLevel) {
        this.executable = constructor;
        this.parameterIndex = validateIndex(constructor, parameterIndex);
        this.nestingLevel = nestingLevel;
    }
    
    /**
     * 用于创建已设置包含类的 {@link MethodParameter} 的内部构造函数
     *
     * @param executable      可执行文件以指定参数
     * @param parameterIndex  参数索引
     * @param containingClass 包含类
     */
    MethodParameter(@NotNull Executable executable, int parameterIndex, @Nullable Class<?> containingClass) {
        this.executable = executable;
        this.parameterIndex = validateIndex(executable, parameterIndex);
        this.nestingLevel = 1;
        this.containingClass = containingClass;
    }
    
    /**
     * 复制构造函数，从而基于原始对象所在的相同元数据和缓存状态生成独立的 MethodParameter 对象
     */
    public MethodParameter(@NotNull MethodParameter original) {
        this.executable = original.executable;
        this.parameterIndex = original.parameterIndex;
        this.parameter = original.parameter;
        this.nestingLevel = original.nestingLevel;
        this.typeIndexesPerLevel = original.typeIndexesPerLevel;
        this.containingClass = original.containingClass;
        this.parameterType = original.parameterType;
        this.genericParameterType = original.genericParameterType;
        this.parameterAnnotations = original.parameterAnnotations;
        this.parameterNameDiscoverer = original.parameterNameDiscoverer;
        this.parameterName = original.parameterName;
    }
    
    /**
     * 为给定的方法或构造函数创建一个新的MethodParameter。
     *
     * @param executable     方法或构造函数
     * @param parameterIndex 参数的索引
     * @return 相应的 MethodParameter 实例
     */
    @Contract("null, _ -> fail")
    public static @NotNull MethodParameter forExecutable(Executable executable, int parameterIndex) {
        if (executable instanceof Method) {
            return new MethodParameter((Method) executable, parameterIndex);
        } else if (executable instanceof Constructor) {
            return new MethodParameter((Constructor<?>) executable, parameterIndex);
        } else {
            throw new IllegalArgumentException("不是 Method 或者 Constructor: " + executable);
        }
    }
    
    /**
     * 为给定的参数描述符创建一个新的MethodParameter
     * <p>
     * 这是一个方便的工厂方法，适用于已经有一个Java 8 {@link Parameter}描述符的情况。
     *
     * @param parameter 参数描述符
     * @return 相应的 MethodParameter 实例
     */
    public static @NotNull MethodParameter forParameter(@NotNull Parameter parameter) {
        return forExecutable(parameter.getDeclaringExecutable(), findParameterIndex(parameter));
    }
    
    protected static int findParameterIndex(@NotNull Parameter parameter) {
        Executable executable = parameter.getDeclaringExecutable();
        Parameter[] allParams = executable.getParameters();
        // 首先尝试用身份检查，以获得更大的性能。
        for (int i = 0; i < allParams.length; i++) {
            if (parameter == allParams[i]) {
                return i;
            }
        }
        // 为了避免在调用java.lang.reflect.Executable.getParameters()时出现竞赛条件，有可能再次尝试对象平等检查。
        for (int i = 0; i < allParams.length; i++) {
            if (parameter.equals(allParams[i])) {
                return i;
            }
        }
        throw new IllegalArgumentException("给定的参数[" + parameter + "]不符合声明的可执行文件中的任何参数");
    }
    
    @Contract("_, _ -> param2")
    private static int validateIndex(@NotNull Executable executable, int parameterIndex) {
        int count = executable.getParameterCount();
        if (!(parameterIndex >= -1 && parameterIndex < count)) {
            throw new IllegalArgumentException("参数索引需要在 -1 和 " + (count - 1));
        }
        return parameterIndex;
    }
    
    /**
     * 返回包装的方法
     */
    @Nullable
    public Method getMethod() {
        return (this.executable instanceof Method ? (Method) this.executable : null);
    }
    
    /**
     * 返回构造函数
     */
    @Nullable
    public Constructor<?> getConstructor() {
        return (this.executable instanceof Constructor ? (Constructor<?>) this.executable : null);
    }
    
    /**
     * 返回声明基础方法或构造函数的类
     */
    public Class<?> getDeclaringClass() {
        return this.executable.getDeclaringClass();
    }
    
    /**
     * 返回包装的可执行对象
     */
    public Executable getExecutable() {
        return this.executable;
    }
    
    /**
     * 返回方法构造函数参数的 {@link Parameter} 描述符
     */
    public Parameter getParameter() {
        if (this.parameterIndex < 0) {
            throw new IllegalStateException("无法检索方法返回类型的参数描述符");
        }
        Parameter parameter = this.parameter;
        if (parameter == null) {
            parameter = getExecutable().getParameters()[this.parameterIndex];
            this.parameter = parameter;
        }
        return parameter;
    }
    
    /**
     * 返回方法构造函数参数的索引
     *
     * @return 参数索引（返回类型为 -1）
     */
    public int getParameterIndex() {
        return this.parameterIndex;
    }
    
    /**
     * 返回目标类型的嵌套级别（通常为 1;例如，在列表列表的情况下，1 表示嵌套列表，而 2 表示嵌套列表的元素）
     */
    public int getNestingLevel() {
        return this.nestingLevel;
    }
    
    /**
     * 返回此 {@code 方法参数} 的变体，其中当前级别的类型设置为指定值。
     *
     * @param typeIndex the new type index
     */
    public MethodParameter withTypeIndex(int typeIndex) {
        return nested(this.nestingLevel, typeIndex);
    }
    
    /**
     * 返回当前嵌套层的类型索引
     *
     * @return 相应的类型索引，或者{@code null} 如果没有指定（表示默认的类型索引）
     * @see #getNestingLevel()
     */
    @Nullable
    public Integer getTypeIndexForCurrentLevel() {
        return getTypeIndexForLevel(this.nestingLevel);
    }
    
    /**
     * 返回指定嵌套级别的类型索引
     *
     * @param nestingLevel 要检查的嵌套级别
     * @return 相应的类型索引，或者{@code null} 如果没有指定（表示默认的类型索引）。
     */
    @Nullable
    public Integer getTypeIndexForLevel(int nestingLevel) {
        return getTypeIndexesPerLevel().get(nestingLevel);
    }
    
    /**
     * 获得（懒惰地构建的）每层类型索引图
     */
    private Map<Integer, Integer> getTypeIndexesPerLevel() {
        if (this.typeIndexesPerLevel == null) {
            this.typeIndexesPerLevel = new HashMap<>(4);
        }
        return this.typeIndexesPerLevel;
    }
    
    /**
     * 返回这个{@code MethodParameter}的变体，该变体指向相同的参数，但要深入一个嵌套级别。
     */
    public MethodParameter nested() {
        return nested(null);
    }
    
    /**
     * 返回这个{@code MethodParameter}的变体，该变体指向相同的参数，但要深入一个嵌套级别。
     *
     * @param typeIndex 新嵌套层的类型索引
     */
    public MethodParameter nested(@Nullable Integer typeIndex) {
        MethodParameter nestedParam = this.nestedMethodParameter;
        if (nestedParam != null && typeIndex == null) {
            return nestedParam;
        }
        nestedParam = nested(this.nestingLevel + 1, typeIndex);
        if (typeIndex == null) {
            this.nestedMethodParameter = nestedParam;
        }
        return nestedParam;
    }
    
    private @NotNull MethodParameter nested(int nestingLevel, @Nullable Integer typeIndex) {
        MethodParameter copy = clone();
        copy.nestingLevel = nestingLevel;
        if (this.typeIndexesPerLevel != null) {
            copy.typeIndexesPerLevel = new HashMap<>(this.typeIndexesPerLevel);
        }
        if (typeIndex != null) {
            copy.getTypeIndexesPerLevel().put(copy.nestingLevel, typeIndex);
        }
        copy.parameterType = null;
        copy.genericParameterType = null;
        return copy;
    }
    
    /**
     * 返回该方法是否指示了一个不需要的参数
     * 无论是Java 8的{@link java.util.Optional}形式，还是参数级 {@code Nullable} 注解的任何变体（例如来自JSR-305或 FindBugs 注解集），
     * 或者语言级的 nullable 类型声明或 Kotlin 的{@code Continuation} 参数。
     */
    public boolean isOptional() {
        return (getParameterType() == Optional.class || hasNullableAnnotation() ||
                (KotlinDetector.isKotlinReflectPresent() &&
                        KotlinDetector.isKotlinType(getContainingClass()) &&
                        KotlinDelegate.isOptional(this)));
    }
    
    /**
     * 检查此方法参数是否被注解为 {@code Nullable} 注解的任何变体，
     * 例如 {@code jakarta.annotation.Nullable} 或  {@code edu.umd.cs.findbugs.annotations.Nullable}。
     */
    private boolean hasNullableAnnotation() {
        for (Annotation ann : getParameterAnnotations()) {
            if ("Nullable".equals(ann.annotationType().getSimpleName())) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 返回这个 {@code MethodParameter} 的变体，它指向相同的参数，但在 {@link java.util.Optional}声明的情况下，是一个更深的嵌套级别。
     *
     * @see #isOptional()
     * @see #nested()
     */
    public MethodParameter nestedIfOptional() {
        return isOptional() ? nested() : this;
    }
    
    /**
     * 返回这个 {@code MethodParameter} 的一个变体，它指的是给定的包含类。
     *
     * @param containingClass 一个特定的包含类（可能是声明类的一个子类，例如，替换一个类型变量）
     * @see #getParameterType()
     */
    public MethodParameter withContainingClass(@Nullable Class<?> containingClass) {
        MethodParameter result = clone();
        result.containingClass = containingClass;
        result.parameterType = null;
        return result;
    }
    
    /**
     * 返回该方法参数的包含类
     *
     * @return 一个特定的包含类（可能是声明类的一个子类），或者仅仅是声明类本身
     * @see #getDeclaringClass()
     */
    public Class<?> getContainingClass() {
        Class<?> containingClass = this.containingClass;
        return (containingClass != null ? containingClass : getDeclaringClass());
    }
    
    /**
     * 返回方法/构造器参数的类型
     *
     * @return 参数的类型（绝不是{@code null}）
     */
    public Class<?> getParameterType() {
        Class<?> paramType = this.parameterType;
        if (paramType != null) {
            return paramType;
        }
        if (getContainingClass() != getDeclaringClass()) {
            paramType = ResolvableType.forMethodParameter(this, null, 1).resolve();
        }
        if (paramType == null) {
            paramType = computeParameterType();
        }
        this.parameterType = paramType;
        return paramType;
    }
    
    /**
     * 返回方法/构造函数参数的通用类型
     *
     * @return 参数的类型（绝不是{@code null}）
     */
    public Type getGenericParameterType() {
        Type paramType = this.genericParameterType;
        if (paramType == null) {
            if (this.parameterIndex < 0) {
                Method method = getMethod();
                if (method != null) {
                    if (KotlinDetector.isKotlinType(getContainingClass())) {
                        paramType = KotlinDelegate.getGenericReturnType(method);
                    } else {
                        paramType = method.getGenericReturnType();
                    }
                } else {
                    paramType = void.class;
                }
                
            } else {
                Type[] genericParameterTypes = this.executable.getGenericParameterTypes();
                int index = this.parameterIndex;
                if (this.executable instanceof Constructor &&
                        ClassUtil.isInnerClass(this.executable.getDeclaringClass()) &&
                        genericParameterTypes.length == this.executable.getParameterCount() - 1) {
                    // javac中的错误：对于至少有一个通用构造函数参数的内部类，类型数组不包括包围的实例参数，
                    // 所以访问它时，实际的参数索引降低了1。
                    index = this.parameterIndex - 1;
                }
                paramType = (index >= 0 && index < genericParameterTypes.length ?
                        genericParameterTypes[index] : computeParameterType());
            }
            this.genericParameterType = paramType;
        }
        return paramType;
    }
    
    private Class<?> computeParameterType() {
        if (this.parameterIndex < 0) {
            Method method = getMethod();
            if (method == null) {
                return void.class;
            }
            if (KotlinDetector.isKotlinType(getContainingClass())) {
                return KotlinDelegate.getReturnType(method);
            }
            return method.getReturnType();
        }
        return this.executable.getParameterTypes()[this.parameterIndex];
    }
    
    /**
     * 返回方法/构造器参数的嵌套类型
     *
     * @return 参数的类型（绝不是{@code null}）
     * @see #getNestingLevel()
     */
    public Class<?> getNestedParameterType() {
        if (this.nestingLevel > 1) {
            Type type = getGenericParameterType();
            for (int i = 2; i <= this.nestingLevel; i++) {
                if (type instanceof ParameterizedType) {
                    Type[] args = ((ParameterizedType) type).getActualTypeArguments();
                    Integer index = getTypeIndexForLevel(i);
                    type = args[index != null ? index : args.length - 1];
                }
            }
            
            if (type instanceof Class) {
                return (Class<?>) type;
            } else if (type instanceof ParameterizedType) {
                Type arg = ((ParameterizedType) type).getRawType();
                if (arg instanceof Class) {
                    return (Class<?>) arg;
                }
            }
            
            // 如果无法解析返回 Object.class
            return Object.class;
        } else {
            return getParameterType();
        }
    }
    
    /**
     * 返回方法/构造函数参数的嵌套通用类型
     *
     * @return 参数的类型（绝不是{@code null}）
     * @see #getNestingLevel()
     */
    public Type getNestedGenericParameterType() {
        if (this.nestingLevel > 1) {
            Type type = getGenericParameterType();
            for (int i = 2; i <= this.nestingLevel; i++) {
                if (type instanceof ParameterizedType) {
                    Type[] args = ((ParameterizedType) type).getActualTypeArguments();
                    Integer index = getTypeIndexForLevel(i);
                    type = args[index != null ? index : args.length - 1];
                }
            }
            return type;
        } else {
            return getGenericParameterType();
        }
    }
    
    /**
     * 返回与目标方法/构造器本身相关的注释
     */
    public Annotation[] getMethodAnnotations() {
        return adaptAnnotationArray(getExecutable().getAnnotations());
    }
    
    /**
     * 如果有的话，返回给定类型的方法/构造器注释
     *
     * @param annotationType 要寻找的注释类型
     * @return 注释对象，如果没有找到，则{@code null}
     */
    @Nullable
    public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
        A annotation = getExecutable().getAnnotation(annotationType);
        return (annotation != null ? adaptAnnotation(annotation) : null);
    }
    
    /**
     * 返回该方法/构造函数是否有给定类型的注释
     *
     * @param annotationType 要寻找的注释类型
     * @see #getMethodAnnotation(Class)
     */
    public <A extends Annotation> boolean hasMethodAnnotation(Class<A> annotationType) {
        return getExecutable().isAnnotationPresent(annotationType);
    }
    
    /**
     * 返回与特定方法/构造函数参数相关的注释
     */
    public Annotation[] getParameterAnnotations() {
        if (this.parameterAnnotations == null) {
            Parameter parameter = getParameter();
            this.parameterAnnotations = AnnotatedElementUtils.getAnnotations(parameter, true);
        }
        return this.parameterAnnotations;
    }
    
    /**
     * 如果参数至少有一个注释，返回{@code true}；如果没有注释，返回{@code false}
     *
     * @see #getParameterAnnotations()
     */
    public boolean hasParameterAnnotations() {
        return (getParameterAnnotations().length != 0);
    }
    
    /**
     * 返回给定类型的参数注解，如果有的话
     *
     * @param annotationType 要寻找的注释类型
     * @return 注释对象，如果没有找到，则{@code null}
     */
    @SuppressWarnings("unchecked")
    @Nullable
    public <A extends Annotation> A getParameterAnnotation(Class<A> annotationType) {
        Annotation[] anns = getParameterAnnotations();
        for (Annotation ann : anns) {
            if (annotationType.isInstance(ann)) {
                return (A) ann;
            }
        }
        return null;
    }
    
    /**
     * 返回参数是否以给定的注解类型声明
     *
     * @param annotationType 要寻找的注释类型
     * @see #getParameterAnnotation(Class)
     */
    public <A extends Annotation> boolean hasParameterAnnotation(Class<A> annotationType) {
        return (getParameterAnnotation(annotationType) != null);
    }
    
    /**
     * 为这个方法参数初始化参数名称发现
     * <p>
     * 这个方法实际上并不试图在此时检索参数名称，它只是允许在应用程序调用 {@link #getParameterName()}时发生发现（如果有的话）
     */
    public void initParameterNameDiscovery(@Nullable ParameterNameDiscoverer parameterNameDiscoverer) {
        this.parameterNameDiscoverer = parameterNameDiscoverer;
    }
    
    /**
     * 返回方法/构造器参数的名称
     *
     * @return 参数名称（如果在类文件中没有包含参数名称元数据，或者没有 {@link #initParameterNameDiscovery ParameterNameDiscoverer} 被设置为开始，则可能是{@code null}）。
     */
    @Nullable
    public String getParameterName() {
        if (this.parameterIndex < 0) {
            return null;
        }
        
        ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;
        if (discoverer != null) {
            String[] parameterNames = null;
            if (this.executable instanceof Method) {
                parameterNames = discoverer.getParameterNames((Method) this.executable);
            } else if (this.executable instanceof Constructor) {
                parameterNames = discoverer.getParameterNames((Constructor<?>) this.executable);
            }
            if (parameterNames != null) {
                this.parameterName = parameterNames[this.parameterIndex];
            }
            this.parameterNameDiscoverer = null;
        }
        
        return this.parameterName;
    }
    
    /**
     * 一个模板方法，在将一个给定的注释实例返回给调用者之前，对其进行后处理
     * <p>
     * 默认实现只是按原样返回给定的注解
     *
     * @param annotation 将要返回的注释
     * @return 经过处理的注释（或仅仅是原始注释）
     */
    protected <A extends Annotation> A adaptAnnotation(A annotation) {
        return annotation;
    }
    
    /**
     * 一个模板方法，在将给定的注释数组返回给调用者之前对其进行后处理
     * <p>
     * 默认实现只是按原样返回给定的注释数组
     *
     * @param annotations 将要返回的注释阵列
     * @return 后处理的注释阵列（或简单的原始注释）
     */
    protected Annotation[] adaptAnnotationArray(Annotation[] annotations) {
        return annotations;
    }
    
    @Override
    public boolean equals(@Nullable Object other) {
        if (this == other) {
            return true;
        }
        if (!(other instanceof MethodParameter)) {
            return false;
        }
        MethodParameter otherParam = (MethodParameter) other;
        return (getContainingClass() == otherParam.getContainingClass() &&
                Utils.nullSafeEquals(this.typeIndexesPerLevel, otherParam.typeIndexesPerLevel) &&
                this.nestingLevel == otherParam.nestingLevel &&
                this.parameterIndex == otherParam.parameterIndex &&
                this.executable.equals(otherParam.executable));
    }
    
    @Override
    public int hashCode() {
        return (31 * this.executable.hashCode() + this.parameterIndex);
    }
    
    @Override
    public String toString() {
        Method method = getMethod();
        return (method != null ? "method '" + method.getName() + "'" : "constructor") +
                " parameter " + this.parameterIndex;
    }
    
    @Override
    public MethodParameter clone() {
        return new MethodParameter(this);
    }
    
    /**
     * 内部类，以避免在运行时对 Kotlin 的硬性依赖。
     */
    private static class KotlinDelegate {
        
        /**
         * 检查指定的{@link MethodParameter}是否代表一个可归零的Kotlin类型，
         * 一个可选参数（在Kotlin声明中具有默认值）或一个用于中止函数的 {@code Continuation}参数。
         */
        public static boolean isOptional(@NotNull MethodParameter param) {
            Method method = param.getMethod();
            int index = param.getParameterIndex();
            if (method != null && index == -1) {
                KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
                return (function != null && function.getReturnType().isMarkedNullable());
            }
            KFunction<?> function;
            Predicate<KParameter> predicate;
            if (method != null) {
                if (param.getParameterType().getName().equals("kotlin.coroutines.Continuation")) {
                    return true;
                }
                function = ReflectJvmMapping.getKotlinFunction(method);
                predicate = p -> KParameter.Kind.VALUE.equals(p.getKind());
            } else {
                Constructor<?> ctor = param.getConstructor();
                if (Objects.isNull(ctor)) {
                    throw new IllegalArgumentException("既没有找到方法也没有找到构造函数");
                }
                function = ReflectJvmMapping.getKotlinFunction(ctor);
                predicate = p -> (KParameter.Kind.VALUE.equals(p.getKind()) ||
                        KParameter.Kind.INSTANCE.equals(p.getKind()));
            }
            if (function != null) {
                int i = 0;
                for (KParameter kParameter : function.getParameters()) {
                    if (predicate.test(kParameter)) {
                        if (index == i++) {
                            return (kParameter.getType().isMarkedNullable() || kParameter.isOptional());
                        }
                    }
                }
            }
            return false;
        }
        
        /**
         * 返回方法的通用返回类型，支持通过Kotlin反射暂停函数。
         */
        private static Type getGenericReturnType(Method method) {
            try {
                KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
                if (function != null && function.isSuspend()) {
                    return ReflectJvmMapping.getJavaType(function.getReturnType());
                }
            } catch (UnsupportedOperationException ex) {
                // 可能是一个合成类-- 让我们用java的反射来代替。
            }
            return method.getGenericReturnType();
        }
        
        /**
         * 返回方法的返回类型，支持通过Kotlin反射暂停函数。
         */
        private static Class<?> getReturnType(Method method) {
            try {
                KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
                if (function != null && function.isSuspend()) {
                    Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType());
                    if (paramType == Unit.class) {
                        paramType = void.class;
                    }
                    return ResolvableType.forType(paramType).resolve(method.getReturnType());
                }
            } catch (UnsupportedOperationException ex) {
                // 可能是一个合成类-- 让我们用java的反射来代替。
            }
            return method.getReturnType();
        }
    }
    
}
